/*
 * SongPanel.java
 *
 * Created on 24.5.2009, 14:13:25
 */

package org.marvec.pisnickar.panels;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.lobobrowser.html.UserAgentContext;
import org.lobobrowser.html.parser.DocumentBuilderImpl;
import org.lobobrowser.html.parser.InputSourceImpl;
import org.lobobrowser.html.test.SimpleUserAgentContext;
import org.marvec.pisnickar.html.GlobalHtmlListener;
import org.marvec.pisnickar.html.HtmlListener;
import org.marvec.pisnickar.html.LocalHtmlRendererContext;
import org.marvec.pisnickar.songs.Song;
import org.marvec.pisnickar.songs.SongSource;
import org.marvec.pisnickar.songs.SourceManager;
import org.marvec.pisnickar.tabs.TabManipulator;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 *
 * @author marvec
 */
public class SongPanel extends javax.swing.JPanel {
    private static final long serialVersionUID = -1137344751749815291L;

    private SourceManager sources;
    private SongSource source;
    private String songId;
    private HtmlListener listener;
    private Song song;
    private TabManipulator manipulator;

    private UserAgentContext ucontext = null;
    private LocalHtmlRendererContext rcontext = null;
    private DocumentBuilderImpl dbi = null;


    /** Creates new form SongPanel */
    public SongPanel(HtmlListener listener, TabManipulator manipulator, SourceManager sources, SongSource source, String songId, Song song) {
        this.sources = sources;
        this.listener = listener;
        this.source = source;
        this.songId = songId;
        this.song = song;
        this.manipulator = manipulator;

        initComponents();
        initHtmlPanel();
        initTransposeListener();
    }

    public void refresh(Song song) {
        this.song = song;
        initHtmlPanel();
    }

    private void setTranspose(Integer transpose) {
        song.setTranspose(transpose);
        refresh(song);
    }

    public void initTransposeListener() {
        final SongPanel panel = this;

        transposeSpinner.getModel().addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                panel.setTranspose((Integer) transposeSpinner.getModel().getValue());
            }
        });
    }

    protected Reader getResource() throws UnsupportedEncodingException {
        return new StringReader(song.toHtml(source.getId(), songId, source.isReadOnly()));
    }

    private void initHtmlPanel() {
        try {
            if (ucontext == null || rcontext == null || dbi == null) { // is it neccessary to reinitialize?
                ucontext = new SimpleUserAgentContext();
                rcontext = new LocalHtmlRendererContext(htmlPanel1, ucontext);
                rcontext.addHtmlListener(listener);
                rcontext.setSupressOriginalHanlder(true);
                dbi = new DocumentBuilderImpl(ucontext, rcontext);
            }
            Document document = dbi.parse(new InputSourceImpl(getResource(), GlobalHtmlListener.INTERNAL_URL_PREFIX));
            htmlPanel1.setDocument(document, rcontext);
        } catch (SAXException ex) {
            Logger.getLogger(SongPanel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(SongPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        htmlPanel1 = new org.lobobrowser.html.gui.HtmlPanel();
        jToolBar1 = new javax.swing.JToolBar();
        jLabel1 = new javax.swing.JLabel();
        jSeparator2 = new javax.swing.JToolBar.Separator();
        transposeSpinner = new javax.swing.JSpinner();
        jSeparator1 = new javax.swing.JToolBar.Separator();
        addToSelectionButton = new javax.swing.JButton();

        setName("Form"); // NOI18N

        htmlPanel1.setName("htmlPanel1"); // NOI18N

        jToolBar1.setRollover(true);
        jToolBar1.setName("jToolBar1"); // NOI18N

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(org.marvec.pisnickar.PisnickarApp.class).getContext().getResourceMap(SongPanel.class);
        jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
        jLabel1.setName("jLabel1"); // NOI18N
        jToolBar1.add(jLabel1);

        jSeparator2.setName("jSeparator2"); // NOI18N
        jToolBar1.add(jSeparator2);

        transposeSpinner.setModel(new javax.swing.SpinnerNumberModel(0, -12, 12, 1));
        transposeSpinner.setMaximumSize(new java.awt.Dimension(80, 32767));
        transposeSpinner.setName("transposeSpinner"); // NOI18N
        jToolBar1.add(transposeSpinner);

        jSeparator1.setName("jSeparator1"); // NOI18N
        jToolBar1.add(jSeparator1);

        addToSelectionButton.setText(resourceMap.getString("addToSelectionButton.text")); // NOI18N
        addToSelectionButton.setFocusable(false);
        addToSelectionButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        addToSelectionButton.setName("addToSelectionButton"); // NOI18N
        addToSelectionButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        addToSelectionButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addToSelectionButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(addToSelectionButton);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 402, Short.MAX_VALUE)
            .addComponent(htmlPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 402, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0)
                .addComponent(htmlPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 308, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void addToSelectionButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addToSelectionButtonActionPerformed
        SongSource ss = sources.getDummySongSource();
        try {
            ss.storeSong(null, (Song) song.clone());
        } catch (IOException e) {
            // this should not happen
        }
        manipulator.refreshSelection();
    }//GEN-LAST:event_addToSelectionButtonActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addToSelectionButton;
    private org.lobobrowser.html.gui.HtmlPanel htmlPanel1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JToolBar.Separator jSeparator2;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JSpinner transposeSpinner;
    // End of variables declaration//GEN-END:variables

}
